// altnpc.txt
// An alternate version of basicnpc that I use now. Allows you to run a state when a creature dies (instead of incrementing a flag), can run either dialog nodes or town states when talked to (thus allowing you to trigger more complex sequences from dialog), combines some of the groupnpc functionality by allowing you to add creatures to groups using memory cells (doesn't alert the creature's group though, you have to add that yourself if you want it), and allows you to control whether an NPC talks or not by setting flags. Creature's attack AI has been left completely unchanged, so you can replace basicnpc with this script without any problems.
// Memory Cells:
//   Cell 0 - How creature moves.
//     0 - If 0, wander randomly. 
//     1 - Stands still until a target appears.
//     2 - Completely immobile, even if target appears.
//   Cell 1 - State to call when creature dies.
//   Cell 2 - group to add creature to.
//   Cell 3 - Number of a dialog node or a state in a town script to run when talked to.
//   Cell 4 - Town script or Dialog. If left at zero will use dialog nodes, else will use a town script.
//   Cell 5 - Unused
//   Cell 6,7 - Flag for dialog
//   Cell 8 - Value that flag must be for dialog to run.
//   Cell 9 - starting pose
begincreaturescript;

variables;

short i,target;

body;

beginstate INIT_STATE;
	if (get_memory_cell(0) == 2)
		set_mobility(ME,0);
	if((get_memory_cell(2) > 0) && (get_memory_cell(2) <= 7))
		add_char_to_group(my_number(),get_memory_cell(2));
	if((get_memory_cell(9) > 0) && (get_memory_cell(9) <= 14))
		set_character_pose(me,get_memory_cell(9));
	break;

beginstate DEAD_STATE;
	if (get_memory_cell(1) != 0)
		run_town_script(get_memory_cell(1));
break;

beginstate START_STATE; 
	// if I have a target for some reason, go attack it
	if (target_ok()) {
		if (dist_to_char(get_target()) <= 16)
			set_state(3);
			else set_target(ME,-1);
		}
	
	// Look for a target, attack it if visible
	if (select_target(ME,8,0)) {
		do_attack();
		set_state(3);
		}
		
	// Have I been hit? Strike back!
	if (who_hit_me() >= 0) {
		set_target(ME,who_hit_me());
		do_attack();
		set_state(3);
		}
		
	// Otherwise, just peacefully move around. Go back to start, if I'm too far
	// from where I started.
	if ((my_dist_from_start() >= 6) || ((my_dist_from_start() > 0) && (get_memory_cell(0) > 0))) {
		if (get_ran(1,1,100) < 40) 
			return_to_start(ME,1);
		}
		else if (get_memory_cell(0) == 0) {
			fidget(ME,25);
			}

	// if we're in combat and the above didn't give me anything to do, just
	// stop now. Otherwise, game will keep running script, and that eats up CPU time.
	if (am_i_doing_action() == FALSE)
		end_combat_turn();
break;

beginstate 3; // attacking
	if (target_ok() == FALSE)
		set_state(START_STATE);
	do_attack();
break;

beginstate TALKING_STATE;
	if((get_memory_cell(6) > 0) || (get_memory_cell(7) > 0))
		if(get_flag(get_memory_cell(6),get_memory_cell(7)) != get_memory_cell(8)){
			print_str("Talking: It doesn't respond.");
			end();
		}
	if (get_memory_cell(3) > 0){
		if(get_memory_cell(4) == 0)
			begin_talk_mode(get_memory_cell(3));
		else
			run_town_script(get_memory_cell(3));
	}
	else
		print_str("Talking: It doesn't respond.");
break;